package com.bytebuddytest.classcreation;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author yutianhong
 * @version 1.0
 * @since 2023/08/15 18:54:02
 */
public class ByteBuddyClassLoaderTest {

    @Test
    public void testWrapperClassLoadingStrategy() {
        Class<?> type = new ByteBuddy()
                .subclass(Object.class)
                .make()
                .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
                .getLoaded();
        System.out.println("type = " + type);
        // net.bytebuddy.dynamic.loading.ByteArrayClassLoader@bccb269
        System.out.println("type.getClassLoader() = " + type.getClassLoader());
    }

    @Test
    public void testInjectionClassLoadingStrategy() {
        Class<?> type = new ByteBuddy()
                .subclass(Object.class)
                .make()
                .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
                .getLoaded();
        System.out.println("type = " + type);
        // sun.misc.Launcher$AppClassLoader@18b4aac2
        System.out.println("type.getClassLoader() = " + type.getClassLoader());
        Assertions.assertSame(type.getClassLoader(), getClass().getClassLoader());
    }

    @Test
    public void testPersistentClassLoadingStrategy() throws IOException {
        Class<?> type = new ByteBuddy()
                .subclass(Foo.class)
                .name("example.Baz")
                .make()
                .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER_PERSISTENT)
                .getLoaded();

        InputStream classIs = type.getClassLoader().getResourceAsStream("example/Baz.class");
        @SuppressWarnings("ConstantConditions")
        String path = getClass().getClassLoader().getResource("").getPath() + "Baz.class";
        System.out.println("path = " + path);
        FileUtils.copyToFile(classIs, new File(path));
    }

}
